home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 February: Tool Chest / Dev.CD Feb 94.toast / New System Software Extensions / QuickDraw™ GX v1.0ß2 / Sample Code / Typography Samples / JustLayoutSample ƒ / JustLayoutSample.c next >
Encoding:
C/C++ Source or Header  |  1993-09-09  |  9.6 KB  |  381 lines  |  [TEXT/MPS ]

  1. /*
  2.     Justification Layout Sample Program
  3.     By Eric Mader,
  4.     After Mike Fairman, Oliver Steele et. al.
  5.  
  6.     1.0B2 (MD, 09/09/93) -- insert GXIgnoreGraphicsNotice calls so we're not
  7.     notified that we're setting the text size to the default of 12 points.
  8.  
  9. */
  10.  
  11. /* Copyright ©1989, 1990, 1991 Apple Computer, Inc.  All rights reserved. */
  12.  
  13.  
  14. #ifndef THINK_C
  15. #include <Quickdraw.h>
  16. #include <Fonts.h>
  17. #include <Windows.h>
  18. #include <Dialogs.h>
  19. #include <Events.h>
  20. #include <Memory.h>
  21. #include <Menus.h>
  22. #include <String.h>
  23. #include <Desk.h>
  24. #include <Script.h>
  25. #include <ToolUtils.h>
  26. #define thePort qd.thePort
  27. #define screenBits qd.screenBits
  28. #endif
  29.  
  30. #include "graphics libraries.h"
  31. #include "qd library.h"
  32. #include "graphics debugging.h"
  33. #include "graphics routines.h"
  34. #include "graphics toolbox.h"
  35.  
  36. #include "layout types.h"
  37. #include "layout routines.h"
  38. #include "layout library.h"
  39.  
  40. /* This macro is useful for constructing fixed values */
  41. #define f(a,b) (((fixed) (a) << 16) + (b))
  42.  
  43. /* various menu and dialog things */
  44. enum {aboutDLOG = 128, appleMenuID = 128, fileMenuID, editMenuID}; /* resource ID's */
  45.  
  46. enum {okButton = 1, showsItem, authorItem};
  47.  
  48. enum {
  49.     /* Apple Menu */
  50.     aboutCommand = 1,
  51.     
  52.     /* File Menu */
  53.     quitCommand = 1,
  54.     
  55.     /* Edit Menu */
  56.     undoCommand = 1,
  57.     cutCommand,
  58.     copyCommand,
  59.     pasteCommand,
  60.     clearCommand};
  61.  
  62. WindowPtr myWindow, whichWindow;
  63. gxViewPort myPort;
  64. Rect qdWindowRect;
  65. Rect growRect = {40, 40, 32767, 32767};
  66. Rect bigRect = {-32768, -32768, 32767, 32767};
  67. gxRectangle windowRect;
  68.  
  69. MenuHandle appleMenu, fileMenu, editMenu;
  70. Boolean done = false;
  71.  
  72. gxColor colorWhite = xRGB (0xFFFF, 0xFFFF, 0xFFFF);    /* white */
  73. gxColor hsvInitial = xHSV (0, 0xFFFF, 0xFFFF); /* red */
  74.  
  75. static void ShowAboutBox ()
  76. {    GrafPtr savePort;
  77.     DialogPtr theDialog;
  78.     short itemType;
  79.     Handle itemHdl;
  80.     Rect itemRect;
  81.     short itemHit;
  82.  
  83.     GetPort(&savePort);
  84.     theDialog = GetNewDialog(aboutDLOG, nil, (WindowPtr) -1);
  85.     SetPort(theDialog);
  86.  
  87.     GetDItem(theDialog, authorItem, &itemType, &itemHdl, &itemRect);
  88.     SetIText(itemHdl, (StringPtr) "\pRice Dream");
  89.     GetDItem(theDialog, showsItem, &itemType, &itemHdl, &itemRect);
  90.     SetIText(itemHdl, (StringPtr) "\pJustification");
  91.  
  92.     do {
  93.         ModalDialog(nil, &itemHit);
  94.     } while (itemHit != okButton);
  95.  
  96.     CloseDialog(theDialog);
  97.  
  98.     SetPort(savePort);
  99. }
  100.  
  101. static void SetupMenus ()
  102. {
  103.     InsertMenu (appleMenu = GetMenu (appleMenuID), 0);
  104.     AddResMenu (appleMenu, (ResType) 'DRVR');
  105.     InsertMenu (fileMenu = GetMenu (fileMenuID), 0);
  106.     InsertMenu (editMenu = GetMenu (editMenuID), 0);
  107.     DrawMenuBar ();
  108. }
  109.  
  110. static void DoMenuCommand (long mResult)
  111. {    short theItem = LoWord (mResult), theMenuID = HiWord (mResult);
  112.     GrafPtr savePort;
  113.     Str255 daName;
  114.     
  115.     switch (theMenuID)
  116.     {    case appleMenuID:
  117.             if (theItem == aboutCommand) ShowAboutBox ();
  118.             else
  119.             {    GetItem (appleMenu, theItem, daName);
  120.                 GetPort (&savePort);
  121.                 (void) OpenDeskAcc (daName);
  122.                 SetPort (savePort);
  123.             }
  124.         break;
  125.             
  126.         case fileMenuID:
  127.             if (theItem == quitCommand) done = true;
  128.         break;
  129.             
  130.         case editMenuID:
  131.         break;
  132.     }
  133.     
  134.     HiliteMenu (0);
  135. }
  136.  
  137. static void DrawMargins(fixed top, fixed bottom, fixed margin, fixed width)
  138. { gxLine bound;
  139.  
  140.     bound.first.x = margin; bound.first.y = top;
  141.     bound.last.x = margin; bound.last.y = bottom;
  142.     GXDrawLine(&bound);
  143.     
  144.     bound.first.x += width;
  145.     bound.last.x += width;
  146.     GXDrawLine(&bound);
  147. }
  148.  
  149. void main()
  150. {    EventRecord theEvent;
  151.     gxShape layout1, layout2, layout3, layout4, whiteOut;
  152.     gxRunControls controls;
  153.     gxLayoutOptions gxLayoutOptions;
  154.     StyleRunOverrides overrides;
  155.     gxPriorityJustificationOverride    allToSpace, allToChar;
  156.     char *text1 =
  157.         "The gxLine Layout Manager is a set of support routines";
  158.     char *text2 = 
  159.         "that client programs can call to implement certain";
  160.     char *text3 =
  161.         "functions. It is not a text editor or word processor,";
  162.     char *text4 =
  163.         "although it could certainly be used to implement";
  164.     gxPoint posn;
  165.     GDHandle max;
  166.     short mbh = GetMBarHeight ();
  167.     
  168.     MaxApplZone(); MoreMasters(); MoreMasters();
  169.  
  170.     SetGraphicsLibraryErrors();
  171.     SetGraphicsLibraryNotices ();
  172. /*GXSetValidation(gxInternalValidation | gxStructureValidation | gxNoMemoryManagerValidation);    /* uncomment this for less speed and more error-checking */
  173.  
  174.     InitGraf(&thePort);
  175.     InitFonts();
  176.     InitWindows();
  177.     InitMenus ();
  178.     InitCursor();
  179.  
  180.     SetupMenus ();
  181.     
  182.     /* find the deepest monitor, and make a window that just covers it */
  183.     max = GetMaxDevice (&bigRect);
  184.     qdWindowRect = (**max).gdRect;
  185.     
  186.     /* bring it down one mbh for the header, maybe another if on main screen */
  187.     if (qdWindowRect.top == 0 && qdWindowRect.left == 0) qdWindowRect.top += mbh;
  188.     qdWindowRect.top += mbh;
  189.         
  190.     InsetRect (&qdWindowRect, 4, 4);
  191.     ShortRectToFixed (&qdWindowRect, &windowRect);
  192.     
  193.     myWindow = NewWindow(nil, &qdWindowRect, (StringPtr) "\pJustification Layout Sample",
  194.              true, documentProc, (WindowPtr) -1L, true, 0L);
  195.     
  196.     myPort = GXNewWindowViewPort (myWindow);
  197.     SetDefaultViewPort (myPort);
  198.  
  199.     /*
  200.          When we want to erase the whole window, we just GXDrawShape (whiteOut).
  201.      */
  202.     whiteOut = GXNewShape(gxFullType);
  203.     GXSetShapeColor (whiteOut, &colorWhite);
  204.  
  205.     /* Make a default RuntControls, gxLayoutOptions and StyleRunOverrides */
  206.     InitializeRunControls (&controls);
  207.     InitializeLayoutOptions (&gxLayoutOptions);
  208.     InitializeStyleRunOverrides (&overrides);
  209.     
  210.     /* Set the PriorityJustOverride records to default values */
  211.     SetDefaultPriorityJustOverride (&allToSpace);
  212.     SetDefaultPriorityJustOverride (&allToChar);
  213.     
  214.     /*
  215.         Set the unlimited grow flag for white space, which will cause the
  216.         entire justification gap to be assigned to white space characters
  217.     */
  218.     allToSpace.deltas[gxWhiteSpacePriority].growFlags |= (gxOverrideUnlimited | gxUnlimitedGapAbsorption);
  219.  
  220.     /*
  221.         Set the unlimited grow flag for inter character, which will cause the
  222.         entire justification gap to be assigned to inter character spacing. Also
  223.         override the inter character priority to "kashida" which is the highest
  224.         priority. This will guarantee that inter character spacing is adjusted
  225.         in favor of white space.
  226.     */
  227.     allToChar.deltas[gxInterCharPriority].growFlags |=
  228.         (gxOverrideUnlimited | gxUnlimitedGapAbsorption | gxOverridePriority | gxKashidaPriority);
  229.     
  230.     /*
  231.         We'll set the text to about twice the width really needed
  232.          so that the justification effects are clearly visible.
  233.     */
  234.     gxLayoutOptions.width = ff(468);    /* 6.5 inches * 72 points per inch */
  235.     gxLayoutOptions.just = fract1;            /* full justification */
  236.     
  237.     /*
  238.         Compute the position that would center a layout's baseline
  239.         in the window. We'll draw the lines 30 points apart, so we'll
  240.         put the first two 45 and 15 points above this position and the
  241.         second two 15 and 45 points below it.
  242.     */ 
  243.     posn.x = ((windowRect.right - windowRect.left) - gxLayoutOptions.width) / 2;
  244.     posn.y = ((windowRect.bottom - windowRect.top) / 2) - ff(45);
  245.     
  246.     /* Build a layout for each gxLine */
  247.     GXIgnoreGraphicsNotice(text_size_already_set);
  248.     layout1 = NewSingleLayout (
  249.         text1,
  250.         (char *) "\pTimes Roman",
  251.         ff(12),
  252.         &gxLayoutOptions,
  253.         &posn,
  254.         0,
  255.         &controls,
  256.         nil,
  257.         0,
  258.         nil);
  259.     GXPopGraphicsNotice();
  260.     
  261.     posn.y += ff(30);
  262.     GXIgnoreGraphicsNotice(text_size_already_set);
  263.     layout2 = NewSingleLayout (
  264.         text2,
  265.         (char *) "\pTimes Roman",
  266.         ff(12),
  267.         &gxLayoutOptions,
  268.         &posn,
  269.         0,
  270.         &controls,
  271.         nil,
  272.         0,
  273.         nil);
  274.     GXPopGraphicsNotice();
  275.     
  276.     posn.y += ff(30);
  277.     overrides.priorityJustOverride = &allToSpace;
  278.     GXIgnoreGraphicsNotice(text_size_already_set);
  279.     layout3 = NewSingleLayout (
  280.         text3,
  281.         (char *) "\pTimes Roman",
  282.         ff(12),
  283.         &gxLayoutOptions,
  284.         &posn,
  285.         0,
  286.         &controls,
  287.         nil,
  288.         0,
  289.         &overrides);
  290.     GXPopGraphicsNotice();
  291.     
  292.     posn.y += ff(30);
  293.     overrides.priorityJustOverride = &allToChar;
  294.     GXIgnoreGraphicsNotice(text_size_already_set);
  295.     layout4 = NewSingleLayout (
  296.         text4,
  297.         (char *) "\pTimes Roman",
  298.         ff(12),
  299.         &gxLayoutOptions,
  300.         &posn,
  301.         0,
  302.         &controls,
  303.         nil,
  304.         0,
  305.         &overrides);
  306.     GXPopGraphicsNotice();
  307.  
  308.     GXDrawShape (layout1);
  309.     GXDrawShape (layout2);
  310.     GXDrawShape (layout3);
  311.     GXDrawShape (layout4);
  312.     
  313.     DrawMargins(posn.y - ff(105), posn.y + ff(15), posn.x, gxLayoutOptions.width);
  314.     
  315.     /* Now just spin in a simple event loop until it's time to go */
  316.     while (!done)
  317.     {
  318.         if (WaitNextEvent(everyEvent, &theEvent, 0, nil))
  319.         {
  320.             switch(theEvent.what)
  321.             {
  322.                 case mouseDown:
  323.                 switch (FindWindow(theEvent.where, &whichWindow))
  324.                 {    case inSysWindow:
  325.                         SystemClick(&theEvent, whichWindow);
  326.                         break;
  327.                     
  328.                     case inMenuBar:
  329.                         DoMenuCommand (MenuSelect (theEvent.where));
  330.                     break;
  331.                         
  332.                     case inDrag:
  333.                         DragWindow(whichWindow, theEvent.where, &screenBits.bounds);
  334.                     break;
  335.  
  336.                     case inGrow:
  337.                     {    register long newSize;
  338.  
  339.                         newSize = GrowWindow(whichWindow, theEvent.where, &growRect);
  340.                         SizeWindow(whichWindow, LoWord(newSize), HiWord(newSize), true);
  341.                     }
  342.                     break;
  343.                     
  344.                     case inGoAway:
  345.                         if (TrackGoAway(whichWindow, theEvent.where)) done = true;
  346.                     break;
  347.  
  348.                     case inContent:
  349.                         if (whichWindow != FrontWindow())
  350.                             SelectWindow(whichWindow);
  351.                     break;
  352.                 }
  353.                 break;
  354.  
  355.                 case keyDown:
  356.                 case autoKey:
  357.                     if (myWindow == FrontWindow () && theEvent.modifiers & cmdKey)
  358.                         DoMenuCommand (MenuKey (theEvent.message & charCodeMask));
  359.                 break;
  360.  
  361.                 case updateEvt:
  362.                     BeginUpdate((WindowPtr)theEvent.message);
  363.                     GXDrawShape (whiteOut);
  364.                     GXDrawShape (layout1);
  365.                     GXDrawShape (layout2);
  366.                     GXDrawShape (layout3);
  367.                     GXDrawShape (layout4);
  368.                     DrawMargins(posn.y - ff(105), posn.y + ff(15), posn.x, gxLayoutOptions.width);
  369.                     EndUpdate((WindowPtr)theEvent.message);
  370.                 break;
  371.             }
  372.         }
  373.     }
  374.     /* dispose everything we've allocated. */
  375.     /* If we forget something, we'll get a warning when we call GXExitGraphics */
  376.     GXDisposeShape (layout1); GXDisposeShape (layout2);
  377.     GXDisposeShape (layout3); GXDisposeShape (layout4);
  378.     DisposeWindow(myWindow);
  379.     GXDisposeShape (whiteOut);
  380. }
  381.